package com.gitee.wsl.struct.graph

 class MutableMapGraph<T> internal constructor() : MapGraph<T> {

    override var renderer: (Any?.() -> String) = { this.toString() }

    private val _missingVertexes: MutableSet<T> = mutableSetOf()
    override val missingVertexes: Set<T> = _missingVertexes

    private val map: MutableMap<MapGraph.Vertex<T>, MutableList<MapGraph.Edge<T>>> = mutableMapOf()

    override val entries: Set<Map.Entry<MapGraph.Vertex<T>, List<MapGraph.Edge<T>>>>
        get() = map.entries

    override val keys: Set<MapGraph.Vertex<T>>
        get() = map.keys

    override val size: Int
        get() = map.size

    override val values: Collection<List<MapGraph.Edge<T>>>
        get() = map.values

     fun addVertex(data: T): T {
        val vertex: MapGraph.Vertex<T> = MapGraph.Vertex(this.count(), data)
        map[vertex] = mutableListOf()
        return data
    }

     fun addEdge(source: T, destination: T) {
        val sourceVertex: MapGraph.Vertex<T>? = keys.find { it.value == source }
        val destinationVertex: MapGraph.Vertex<T>? = keys.find { it.value == destination }
        if (sourceVertex == null) _missingVertexes.add(source)
        if (destinationVertex == null) _missingVertexes.add(destination)
        if (sourceVertex != null && destinationVertex != null) {
            val edge: MapGraph.Edge<T> = MapGraph.Edge(sourceVertex, destinationVertex)
            map[sourceVertex]?.add(edge)
        }
    }

    override fun isEmpty(): Boolean = map.isEmpty()

    override fun get(key: MapGraph.Vertex<T>): List<MapGraph.Edge<T>>? = map[key]

    override fun containsValue(value: List<MapGraph.Edge<T>>): Boolean = map.containsValue(value)

    override fun containsKey(key: MapGraph.Vertex<T>): Boolean = map.containsKey(key)

    override fun toString(): String = asString()
}

 fun <T> mutableGraphOf(builderAction: MutableMapGraph<T>.() -> Unit = {}): MutableMapGraph<T> =
    MutableMapGraph<T>().apply(builderAction)